package com.jiaz.untils;

/**
 * @author jiajiazi
 * @version 1.0
 * @date 2022/4/24 13:43
 */

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;

/**
 *  * Json工具类<br>
 *  * 提供序列化和反序列化的统一接口<br>
 * @author jiajiazi
 * @version 1.0
 * @date 2022/4/24 12:06
 */
public final class JsonUtils {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        OBJECT_MAPPER.configure(FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE);
        OBJECT_MAPPER.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, Boolean.FALSE);
    }

    /**
     * 反序列化，将json字符串转化为一个java对象
     *
     * @param json  json字符串
     * @param clazz 映射的java对象
     * @return 返回一个java对象
     */
    public static <T> T toBean(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 反序列化，将json字符串转化为多个相同java对象集合
     *
     * @param json            json字符串
     * @param collectionClass 集合类
     * @param elementClasses  T对象集合
     * @return 返回多个相同java对象集合
     */
    public static <T> T toBeans(String json, Class collectionClass, Class<T> elementClasses) {
        try {
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 反序列化，将json字符串转化为指定对象,并将指定对象中的泛型转为指定的T类型<br>
     * 具体实例参考 @see JsonUtilsTest.toBean1
     *
     * @param data    json字符串
     * @param typeRef TypeReference&lt;xxClass&lt;T&gt;&gt; T为指定要转化为的数据类型
     * @return 返回一个java对象，对象中的泛型转化为指定的T类型
     */
    public static <T> T toBean(String data, TypeReference<T> typeRef) {
        try {
            return (T) OBJECT_MAPPER.readValue(data, typeRef);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 序列化，将一个java对象或java对象集合转化为json字符串
     *
     * @param t java对象引用
     * @return 返回java对象转化的json字符串
     */
    public static <T> String toJson(T t) {
        try {
            return OBJECT_MAPPER.writeValueAsString(t);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 序列化，将一个java对象转化为json字符串，并定制json展示内容
     * 具体实例 @see JsonUtils.toJson1
     *
     * @param t        java对象引用
     * @param jsonView 定制现实内容的java对象
     * @return 返回一个定制内容的json字符串
     */
    public static <T> String toJson(T t, Class jsonView) {
        try {
            return OBJECT_MAPPER.writerWithView(jsonView).writeValueAsString(t);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 返回一个ObjectMapper对象
     *
     * @return 返回一个ObjectMapper对象
     */
    public static ObjectMapper getObjectMapper() {
        return OBJECT_MAPPER;
    }
}

